/**
 * @file Fsim.hh
 * @author Xiaoze Lin (linxiaoze96@gmail.com)
 * @brief The implementation of the Fsim class.
 * @version 0.1
 *
 * @copyright Copyright (c) 2024
 *
 */

#pragma once

#include <filesystem>
#include <string>

#include "AtpgLibrary.hh"
#include "Fault.hh"
#include "FuncPattern.hh"
#include "NetlistManager.hh"
#include "Simulation.hh"
#include "time/Time.hh"
#include "usage/usage.hh"

namespace ifsim {

/**
 * @brief The top Fsim class
 */
class Fsim
{
 public:
  static Fsim* getOrCreateFsim();
  static void destroyFsim();

  void readVerilog(const char* verilog_file);
  void readLibrary(const char* library_file);
  void setCircuitHandling(bool split_tie_flag, int max_fanout, bool dff_buffers_flag);
  void setCircuitHandling();
  void genAndProcessNetlists();
  void createFault();
  void readFaultList(const char* fault_list_file);
  void readPattern(std::string pattern_file);
  void simulatePatterns(int num_thread, bool is_bit_parallel, bool is_vec_mode);

  void topModuleName(const char* top_module_name) { _topModuleName = top_module_name; }
  std::string topModuleName() { return _topModuleName; }

 private:
  Fsim();
  ~Fsim();

  std::string _topModuleName;

  // netlist manager relevant
  NetlistManager* _netlistManager;

  // atpg library relevant
  AtpgLibrary* _atpgLib;

  // fault relevant
  FaultManager* _faultManager;

  // functional pattern relevant
  FuncPatternManager* _funcPatternManager;

  // simulation relevant
  Simulation* _simulation;

  // Singleton atpg.
  static Fsim* _fsim;
};

}  // namespace ifsim